package com.example.spring_source_code;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
import org.springframework.beans.factory.annotation.BeanFactoryAnnotationUtils;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.boot.BootstrapRegistry;
import org.springframework.context.annotation.AnnotationConfigUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.context.support.BeanDefinitionDsl;

import java.util.Map;

public class BeanFactory {
    public static void main(String[] args) {
        //定义BeanFactory
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();

        //描述bean对象
        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(Config.class).setScope("singleton").getBeanDefinition();
        //注入容器BeanFactory
        beanFactory.registerBeanDefinition("config", beanDefinition);
        //给beanFactory添加后置处理器
        AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);
        //执行beanFactory的后置处理器
        Map<String, BeanFactoryPostProcessor> beanFactoryPostProcessorMap = beanFactory.getBeansOfType(BeanFactoryPostProcessor.class);
        beanFactoryPostProcessorMap.values().forEach(beanFactoryPostProcessor -> beanFactoryPostProcessor.postProcessBeanFactory(beanFactory));
        //打印beanFactory中的Bean对象名称
        for (String beanName : beanFactory.getBeanDefinitionNames()) {
            System.out.println(beanName);
        }

        //设置Bean的后置处理器
        Map<String, BeanPostProcessor> beanPostProcessorMap = beanFactory.getBeansOfType(BeanPostProcessor.class);
        beanPostProcessorMap.values().forEach(beanFactory::addBeanPostProcessor);

        //准备好所有的单例对象
        beanFactory.preInstantiateSingletons();

        //从BeanEntity中获取Bean1对象
        BeanEntity beanEntity = beanFactory.getBean(BeanEntity.class);
        Bean1 bean1 = beanEntity.getBean1();
        System.out.println(bean1);
    }


    @Configuration
    static class Config{
        @Bean
        public BeanEntity bean1() {
            return new BeanEntity();
        }


        @Bean
        public Bean1 bean3() {
            return new Bean1();
        }
    }

    static class BeanEntity {
        @Autowired
        private Bean1 bean1;

        public Bean1 getBean1() {
            return bean1;
        }
    }

    static class Bean1 {

    }
}
